/**
 * 
 */
package vn.lumi.smarthome.network;

import java.io.UnsupportedEncodingException;

import vn.lumi.smarthome.LumiHome;
import vn.lumi.smarthome.io.database.TBL_DeviceScene;
import vn.lumi.smarthome.io.database.TBL_DeviceState;
import vn.lumi.smarthome.io.database.TBL_Scene;
import vn.lumi.smarthome.io.model.Device;
import vn.lumi.smarthome.io.model.Scene;
import vn.lumi.smarthome.io.model.Time;
import vn.lumi.smarthome.ulti.Preference;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

/**
 * @author Chu Tuan Anh
 *
 */
public class UpdateSceneInfo extends HCMsg {

	//variables
	private int newConfigVersion = 0;
	private int userId = 0;
	private int sceneId = 0;
	private int roomId = 0;
	private String sceneName = "";
	private int sceneMode = Scene.SCENE_MODE_NORMAL;
	private Time turnOnTime = new Time();
	private int NumOfNormalDevices = 0;
	private int NumOfRGBs = 0;
	private int[] deviceIDList = null;
	private int[] deviceStateList = null;
	private int[] RGBIDList = null;
	private int[] RGBStateList = null;
	
	private boolean isCorrectFormat = false;

	//byte positions
	private static final int userIdPos = 2;
	
	/**
	 * @param cmd_id: command id
	 * @param Msg_id: message id
	 */
	public UpdateSceneInfo(int userId) {
		super(NetMessage.CMD_HC_UPDATE_SCENE_INFO, 0);
		this.userId = userId;
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see vn.lumi.smarthome.network.HCMsg#parseMessage(byte[], int)
	 */
	@Override
	public void parseMessage(byte[] input, int length) {
		// TODO Auto-generated method stub
		isCorrectFormat = isCorrectFormat(input,length);
		if(isCorrectFormat == false) return;
		
		int currentPos = 0;
		this.Cmd_id = Byte2Unsigned(input[currentPos]);
		currentPos++;
		this.newConfigVersion = Byte2Unsigned(input[currentPos]);
		currentPos++;
		this.userId = Byte2Unsigned(input[currentPos]);
		currentPos++;
		this.sceneId = Byte2Unsigned(input[currentPos]);
		currentPos++;
		this.roomId = Byte2Unsigned(input[currentPos]);
		currentPos++;
		
		byte[] name = new byte[30];
		for(int j = 0; j<30; j++){
			name[j] = input[currentPos];
			currentPos++;
		}
		try {
			this.sceneName = new String(name, "UTF-16BE");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		this.sceneMode = Byte2Unsigned(input[currentPos]);
		currentPos++;
		
		this.turnOnTime = new Time(Byte2Unsigned(input[currentPos]), Byte2Unsigned(input[currentPos+1]));
		currentPos+=2;
		
		this.NumOfNormalDevices = Byte2Unsigned(input[currentPos]);
		currentPos++;
		this.NumOfRGBs = Byte2Unsigned(input[currentPos]);
		currentPos++;
		
		this.deviceIDList = new int[this.NumOfNormalDevices];
		this.deviceStateList = new int[this.NumOfNormalDevices];
		this.RGBIDList = new int[this.NumOfRGBs];
		this.RGBStateList = new int[this.NumOfRGBs];
		
		for(int i=0; i<NumOfNormalDevices; i++){
			this.deviceIDList[i] = Byte2Unsigned(input[currentPos]);
			currentPos++;
			this.deviceStateList[i] = Byte2Unsigned(input[currentPos]);
			currentPos++;
		}
		for(int i=0; i<NumOfRGBs; i++){
			this.RGBIDList[i] = Byte2Unsigned(input[currentPos]);
			currentPos++;
			int Red = Byte2Unsigned(input[currentPos]);
			currentPos++;
			int Green = Byte2Unsigned(input[currentPos]);
			currentPos++;
			int Blue = Byte2Unsigned(input[currentPos]);
			currentPos++;
			if(Red == Device.DEVICE_STATE_DEVICE_REMOVED
					&& Green == Device.DEVICE_STATE_DEVICE_REMOVED
					&& Blue == Device.DEVICE_STATE_DEVICE_REMOVED)
				this.RGBStateList[i] = Device.DEVICE_STATE_DEVICE_REMOVED;
			else
				this.RGBStateList[i] = Red*256*256+Green*256+Blue;
		}
	}

	/* (non-Javadoc)
	 * @see vn.lumi.smarthome.network.HCMsg#doWhenReceived(android.content.Context)
	 */
	@Override
	public void doWhenReceived(Context context) {
		// TODO Auto-generated method stub
		if(isCorrectFormat == false) return;
		//find if scene already exists
		String selection = new String(TBL_Scene._ID+"=?");
		String[] selectionArgs = new String[]{this.sceneId+""};
		Cursor cursor = context.getContentResolver().query(TBL_Scene.CONTENT_URI_SCENE, null, selection, selectionArgs, null);
		boolean isNewScene = (cursor.getCount() == 0);
		
		//save scene into database
		ContentValues values = new ContentValues();
		values.put(TBL_Scene.NAME, sceneName);
		values.put(TBL_Scene.ROOM_ID, roomId);
		values.put(TBL_Scene.STATE, Scene.SCENE_STATE_OFF);
		values.put(TBL_Scene._ID, this.sceneId);
		values.put(TBL_Scene.MODE, this.sceneMode);
		values.put(TBL_Scene.HOUR, this.turnOnTime.getHour());
		values.put(TBL_Scene.MINUTE, this.turnOnTime.getMinute());
		if(isNewScene)
			context.getContentResolver().insert(TBL_Scene.CONTENT_URI_SCENE, values);
		else{
			context.getContentResolver().update(TBL_Scene.CONTENT_URI_SCENE, values, selection, selectionArgs);
		}
			
		//delete all in device scene table if update existing scene
		selection = new String(TBL_DeviceScene.SCENE_ID+"=?");
		selectionArgs = new String[]{this.sceneId+""};
		context.getContentResolver().delete(TBL_DeviceScene.CONTENT_URI_DEVICE_SCENE, selection, selectionArgs);
		
		//save device states
			//normal devices
		for(int i=0;i<NumOfNormalDevices;i++){
			//if this device is removed from scene --> do nothing
			if(deviceStateList[i] == Device.DEVICE_STATE_DEVICE_REMOVED)
				continue;
			//insert device state
			ContentValues contentValues=new ContentValues();
			contentValues.put(TBL_DeviceState.VALUE, deviceStateList[i]);
			contentValues.put(TBL_DeviceState.BLIND_STATE, Device.DEVICE_STATE_BLIND_STATE_STOPPED);
			Uri uri2= context.getContentResolver().insert(TBL_DeviceState.CONTENT_URI_DEVICE_STATE, contentValues);
			int state_id=Integer.parseInt(uri2.getLastPathSegment());
			
			//(3) Insert to DeviceScene
			contentValues.clear();
			contentValues.put(TBL_DeviceScene.DEVICE_ID,deviceIDList[i]);
			contentValues.put(TBL_DeviceScene.SCENE_ID,this.sceneId);
			contentValues.put(TBL_DeviceScene.STATE_ID,state_id);
			context.getContentResolver().insert(TBL_DeviceScene.CONTENT_URI_DEVICE_SCENE, contentValues);
		}
			//rgbs
		for(int i=0;i<this.NumOfRGBs;i++){
			//if this device is removed from scene --> do nothing
			if(RGBStateList[i] == Device.DEVICE_STATE_DEVICE_REMOVED)
				continue;
			//insert device state
			ContentValues  contentValues=new ContentValues();
//			int color = this.RGBStateList[3*i] * 256*256 + RGBStateList[3*i+1] *256 + RGBStateList[3*i+2];
			contentValues.put(TBL_DeviceState.RGB, this.RGBStateList[i]);
			Uri uri2= context.getContentResolver().insert(TBL_DeviceState.CONTENT_URI_DEVICE_STATE, contentValues);
			int state_id=Integer.parseInt(uri2.getLastPathSegment());
			
			//(3) Insert to DeviceScene
			contentValues.clear();
			contentValues.put(TBL_DeviceScene.DEVICE_ID,RGBIDList[i]);
			contentValues.put(TBL_DeviceScene.SCENE_ID,this.sceneId);
			contentValues.put(TBL_DeviceScene.STATE_ID,state_id);
			context.getContentResolver().insert(TBL_DeviceScene.CONTENT_URI_DEVICE_SCENE, contentValues);
		}
		
		//save config in preferences
		LumiHome.HC_Config_ver = this.newConfigVersion;
		Preference.saveConfigVersion(context, this.newConfigVersion);
		
		//toast
//		Toast.makeText(context, , duration)
	}
	
	@Override
	public boolean isCorrectFormat(byte[] input, int length){
		boolean result = false;
		if(super.isCorrectFormat(input, length) == false)
			result =  false;
		else{
			if(this.userId == Byte2Unsigned(input[userIdPos])) result =  true;
			else result =  false;
		}
		return result;
	}

}
